package hotel.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import hotel.dao.UserDao;
import hotel.entity.UserEntity;

public class UserDaoImpl implements UserDao 
{
	private static final Logger logger = Logger.getLogger(UserDaoImpl.class);
	private static final String ERROR = "Error in UserDaoImpl:";

	
	private static final String GET_USER_BY_ID_QUERY = "select username, password, name, surname, id, admin from users where id=? ";
	private static final String GET_USER_BY_USERNAME_QUERY = "select username, password, name, surname, id, admin from users where username=? ";
	private static final String GET_USERS_QUERY = "select username, password, name, surname, id, admin from users";
	private static final String DELETE_USER = "delete from users where id=?";
	private static final String INCERT_USER = "insert users(name, surname, username, admin, password)"
			+ " values (?,?,?,?,?)";
	private static final String CHANGE_PASSWORD = "update users set password=? where id=?";
	private static final String UPDATE_USER = "update users "
								+ "set "
								+ "admin = ? "
								+ "where "
								+ "id = ?";
	
	private Connection conn;
	
	public UserDaoImpl(Connection conn)
	{
		this.conn = conn;
	}
	
	@Override
	public UserEntity findById(int id) throws SQLException 
	{
		PreparedStatement stmt = null;
		ResultSet rs = null;
		UserEntity userEntity = null;
		try
		{
			stmt = conn.prepareStatement(UserDaoImpl.GET_USER_BY_ID_QUERY);
			stmt.setInt(1, id);
			rs = stmt.executeQuery();
			if (rs.next()) 
			{
				userEntity = new UserEntity(
									rs.getString("username"),
									rs.getString("password"),
									rs.getString("name"),
									rs.getString("surname"),
									rs.getInt("id"),
									rs.getBoolean("admin"));
			}
		} 
		catch (Exception e) 
		{
			throw e;    
        }
		finally
		{
        	if (rs != null) 
        	{
        		try 
        		{
        			rs.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        	
        	if (stmt != null) 
        	{
        		try 
        		{
        			stmt.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        }
		
		return userEntity;
	}
	
	@Override
	public UserEntity findByUsername(String username) throws SQLException 
	{
		PreparedStatement stmt = null;
		ResultSet rs = null;
		UserEntity userEntity = null;
		try
		{
			stmt = conn.prepareStatement(UserDaoImpl.GET_USER_BY_USERNAME_QUERY);
			stmt.setString(1, username);
			rs = stmt.executeQuery();
			if (rs.next()) 
			{
				userEntity = new UserEntity(
									rs.getString("username"),
									rs.getString("password"),
									rs.getString("name"),
									rs.getString("surname"),
									rs.getInt("id"),
									rs.getBoolean("admin"));
			}
		} 
		catch (Exception e) 
		{
			throw e;    
        }
		finally
		{
        	if (rs != null) 
        	{
        		try 
        		{
        			rs.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        	
        	if (stmt != null) 
        	{
        		try 
        		{
        			stmt.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        }
		
		return userEntity;
	}

	@Override
	public List<UserEntity> findAll() throws SQLException
	{
		List<UserEntity> userEntities = new ArrayList<UserEntity>();
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try
		{
			stmt = conn.prepareStatement(UserDaoImpl.GET_USERS_QUERY);
			rs = stmt.executeQuery();
            while (rs.next())
            {
				userEntities.add( new UserEntity(
									rs.getString("username"),
									rs.getString("password"),
									rs.getString("name"),
									rs.getString("surname"),
									rs.getInt("id"),
									rs.getBoolean("admin")));
			}
            
		} 
		catch (Exception e) 
		{
			throw e;    
        }
		finally
		{
        	if (rs != null) 
        	{
        		try 
        		{
        			rs.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        	
        	if (stmt != null) 
        	{
        		try 
        		{
        			stmt.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        }
		
		return userEntities;
	}

	
	@Override
	public void insert(UserEntity entity) throws SQLException 
	{
		
		PreparedStatement stmt = null;
		try
		{
			stmt = conn.prepareStatement(UserDaoImpl.INCERT_USER);
			stmt.setString(1, entity.getName());
			stmt.setString(2, entity.getSurname());
			stmt.setString(3, entity.getUsername());
			stmt.setBoolean(4, entity.getAdmin());
			stmt.setString(5, entity.getPassword());
			
			stmt.executeUpdate();
		} 
		catch (Exception e) 
		{
			throw e;    
        }
		finally
		{
        	if (stmt != null) 
        	{
        		try 
        		{
        			stmt.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        }
	}

	@Override
	public void update(UserEntity entity) {
		// TODO Auto-generated method stub
	}

	@Override
	public void delete(int id) throws SQLException 
	{
		PreparedStatement stmt = null;
		try
		{
			stmt = conn.prepareStatement(UserDaoImpl.DELETE_USER);
			stmt.setInt(1, id);
			stmt.executeUpdate();
		} 
		catch (Exception e) 
		{
			throw e;    
        }
		finally
		{
        	if (stmt != null) 
        	{
        		try 
        		{
        			stmt.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        }
	}

	public void changePassword(String newPassword, int id) throws SQLException
	{
		PreparedStatement stmt = null;
		try
		{
			stmt = conn.prepareStatement(UserDaoImpl.CHANGE_PASSWORD);
			stmt.setString(1, newPassword);
			stmt.setInt(2, id);
			
			stmt.executeUpdate();
		} 
		catch (Exception e) 
		{
			throw e;    
        }
		finally
		{
        	if (stmt != null) 
        	{
        		try 
        		{
        			stmt.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        }
	}
	
	public void changeRole(boolean role, int id) throws SQLException
	{
		PreparedStatement stmt = null;
		try
		{
			stmt = conn.prepareStatement(UserDaoImpl.UPDATE_USER);
			stmt.setBoolean(1, role);
			stmt.setInt(2, id);

			stmt.executeUpdate();
		} 
		catch (Exception e) 
		{
			throw e;    
        }
		finally
		{
        	if (stmt != null) 
        	{
        		try 
        		{
        			stmt.close();
    			}
        		catch (Exception ignore) 
        		{
        			logger.error(ERROR + ignore);
        		}
        	}
        }
	}
}